package com.waimai1.waimai.common;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.waimai1.waimai.config.PayConfig;
import com.waimai1.waimai.entity.ChoujiangWhite;
import com.wechat.pay.java.core.cipher.PrivacyDecryptor;
import com.wechat.pay.java.core.cipher.RSAPrivacyDecryptor;
import com.wechat.pay.java.core.util.PemUtil;
import org.springframework.http.client.MultipartBodyBuilder;
import org.springframework.util.DigestUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.reactive.function.client.WebClient;
import reactor.core.publisher.Mono;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.GCMParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.lang.model.util.AbstractAnnotationValueVisitor6;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.lang.reflect.Field;
import java.nio.charset.StandardCharsets;
import java.security.*;
import java.util.*;
public class Utils {
    //excel 常量
    static ArrayList<ChoujiangWhite> dataList;
    //网址常量
    final static public String MHId="OP0002";
    final static public String MH_BASE_Url="https://dcopenapi.quanma51.com/api/movie-server/movie";
    static private String HwUrl="https://ot.jfshou.cn/";
    //mahua全局变量token
//    final static public String MHDevCode="beca93a1c82c4a95a7b5aeea4362881b";
//    final static public String MHKey="dc55c136a99a40ee8cd0247830eb9e1b";
//    final static public String MHName="13758175904";
//    final static public String MHPassword="6e83ad0f463767744bf5545ec6e768a6";

    final static public String MHDevCode="48831c743e68468d8e3d3e0ff292bdff";
    final static public String MHKey="3b6997e015504102a6f87692d5887963";
    final static public String MHName="13456800100";
    final static public String MHPassword="ecd784c3f830b66501425dd7b337ef32";
    //福禄常量
    final static public String FlSecret="51190c9e3d7a44dfba534dc9bb430f13";
    final static public String FLAppkey="TqYkaweYpbbeve1gC6WAZeQBaq8E0DtZUE8gfD+u+Hsxk8FgpS00eNFMqYzndedv";
    //mahua地址
    static public Map<String,String> mhUrl;
    static{
        mhUrl=new HashMap<>();
        mhUrl.put("MH_TOKEN","https://dcopenapi.quanma51.com/api/user-server/user/customer/login");
        mhUrl.put("MH_CITY",MH_BASE_Url + "/info/city");
        mhUrl.put("MH_BALANCE",MH_BASE_Url + "/put/account/detail");

//        奈雪
        mhUrl.put("MH_NX_STORE",MH_BASE_Url + "/nx/info/store");
        mhUrl.put("MH_NX_MENU",MH_BASE_Url + "/nx/info/store/menuV2");//菜单
        mhUrl.put("MH_NX_GOOD",MH_BASE_Url + "/nx/info/store/goodDetail");//商品详情
        mhUrl.put("MH_NX_CHECK",MH_BASE_Url + "/nx/putOrder/checkV2");//校验餐品
        mhUrl.put("MH_NX_PUT",MH_BASE_Url + "/nx/putOrder/devadd");//放单
        mhUrl.put("MH_NX_QUERY",MH_BASE_Url + "/nx/putOrder/devdetail");//查询
//        肯德基
        mhUrl.put("MH_KFC_STORE",MH_BASE_Url + "/kfc/info/store");//附近店铺
        mhUrl.put("MH_KFC_MENU",MH_BASE_Url + "/kfc/info/store/menu");//菜单
        mhUrl.put("MH_KFC_GOOD",MH_BASE_Url + "/kfc/info/store/goods");//商品详情
        mhUrl.put("MH_KFC_CHECK",MH_BASE_Url + "/kfc/order/check");//校验餐品
        mhUrl.put("MH_KFC_PUT",MH_BASE_Url + "/kfc/order/put");//放单
        mhUrl.put("MH_KFC_QUERY",MH_BASE_Url + "/kfc/order/query");//查询
        //麦当劳
        mhUrl.put("MH_MCD_STORE",MH_BASE_Url + "/mcd/info/storeByLatAndLng");//附近店铺
        mhUrl.put("MH_MCD_MENU",MH_BASE_Url + "/mcd/info/store/menu");//菜单
        mhUrl.put("MH_MCD_GOOD",MH_BASE_Url + "/mcd/info/store/goods");//商品详情
        mhUrl.put("MH_MCD_CHECK",MH_BASE_Url + "/mcd/order/check");//校验餐品
        mhUrl.put("MH_MCD_PUT",MH_BASE_Url + "/mcd/order/put");//放单
        mhUrl.put("MH_MCD_QUERY",MH_BASE_Url + "/mcd/order/query");//查询
//    星巴克
        mhUrl.put("MH_XBK_STORE",MH_BASE_Url + "/sbk/info/store");//附近店铺
        mhUrl.put("MH_XBK_MENU",MH_BASE_Url + "/sbk/info/goods/info");//菜单
        mhUrl.put("MH_XBK_GOOD",MH_BASE_Url + "/sbk/info/goods/detail");//商品详情
        mhUrl.put("MH_XBK_CHECK",MH_BASE_Url + "/sbk/order/check/v3");//校验餐品
        mhUrl.put("MH_XBK_PUT",MH_BASE_Url + "/sbk/order/put/v2");//放单
        mhUrl.put("MH_XBK_QUERY",MH_BASE_Url + "/sbk/order/query");//查询
//    必胜客
        mhUrl.put("MH_PZH_STORE",MH_BASE_Url + "/pzh/info/storeByLatAndLng");//附近店铺
        mhUrl.put("MH_PZH_MENU",MH_BASE_Url + "/pzh/info/store/menu");//菜单
        mhUrl.put("MH_PZH_GOOD",MH_BASE_Url + "/pzh/info/store/goods");//商品详情
        mhUrl.put("MH_PZH_CHECK",MH_BASE_Url + "/pzh/order/v2/check");//校验餐品
        mhUrl.put("MH_PZH_PUT",MH_BASE_Url + "/pzh/order/v2/put");//放单
        mhUrl.put("MH_PZH_QUERY",MH_BASE_Url + "/pzh/order/v2/query");//查询
//    库迪
        mhUrl.put("MH_COT_STORE",MH_BASE_Url + "/cot/info/storeByLatAndLng");//附近店铺
        mhUrl.put("MH_COT_MENU",MH_BASE_Url + "/cot/info/store/menu");//菜单
        mhUrl.put("MH_COT_GOOD",MH_BASE_Url + "/cot/info/store/goods");//商品详情
        mhUrl.put("MH_COT_CHECK",MH_BASE_Url + "/cot/order/check");//校验餐品
        mhUrl.put("MH_COT_PUT",MH_BASE_Url + "/cot/order/put");//放单
        mhUrl.put("MH_COT_QUERY",MH_BASE_Url + "/cot/order/query");//查询
//    瑞幸
        mhUrl.put("MH_LK_STORE",MH_BASE_Url + "/lk/info/storeByLatAndLng");//附近店铺
        mhUrl.put("MH_LK_MENU",MH_BASE_Url + "/lk/info/store/menu");//菜单
        mhUrl.put("MH_LK_GOOD",MH_BASE_Url + "/lk/info/store/goods");//商品详情
        mhUrl.put("MH_LK_CHECK",MH_BASE_Url + "/lk/order/check");//校验餐品
        mhUrl.put("MH_LK_PUT",MH_BASE_Url + "/lk/order/put");//放单
        mhUrl.put("MH_LK_QUERY",MH_BASE_Url + "/lk/order/query");//查询
//    电影
        mhUrl.put("MH_MAHUA_HOT",MH_BASE_Url + "/info/movieOnInfoList");//电影（热映）
        mhUrl.put("MH_MAHUA_WAIT",MH_BASE_Url + "/info/comingList");//电影（待映）
        mhUrl.put("MH_MAHUA_DETAIL",MH_BASE_Url + "/info/movieDetail");//电影详情
        mhUrl.put("MH_MAHUA_CINEMA",MH_BASE_Url + "/info/cinemaList");//影院列表
        mhUrl.put("MH_MAHUA_PAIPIAN",MH_BASE_Url + "/info/cinema/schedule");//影院排片
        mhUrl.put("MH_MAHUA_PAIPIAN_DETAIL",MH_BASE_Url + "/info/schedule/detail");//排片详情
        mhUrl.put("MH_MAHUA_SEAT",MH_BASE_Url + "/info/cinema/show/seats");//座位情况
        mhUrl.put("MH_MAHUA_BUY",MH_BASE_Url + "/put/add");//放单
        mhUrl.put("MH_MAHUA_QUERY",MH_BASE_Url + "/put/query");//查单
        mhUrl.put("MH_MAHUA_CINEMA_DETAIL",MH_BASE_Url + "/info/cinemaDetail");//影院详情
    }

    //状态常量
    final static public Integer STATUS_WAIT_PAY=1;
    final static public Integer STATUS_PAYED=2;
    final static public Integer STATUS_OVER=3;
    final static public Integer STATUS_CANCEL=4;
    final static public Integer STATUS_WAIT_REFUND=5;
    final static public Integer STATUS_REFUNDED=6;
//    店铺常量
    final static public String SHOP_STATUS_APPLY="已申请";
    final static public String SHOP_STATUS_REFUSE="已拒绝";
    final static public String SHOP_STATUS_PASS="已通过";
    //影院
    final static public String HW_MOVIE_CITY = HwUrl + "ticket/ticket_api/quick/city/query";//城市
    final static public String HW_MOVIE_CINEMA = HwUrl + "ticket/ticket_api/quick/cinema/query";//影院
    final static public String HW_MOVIE_FILM = HwUrl + "ticket/ticket_api/quick/film/query";//电影
    final static public String HW_MOVIE_SHOW = HwUrl + "ticket/ticket_api/quick/show/query";//场次
    final static public String HW_MOVIE_SEAT = HwUrl + "ticket/ticket_api/quick/seat/query";//座位
    final static public String HW_MOVIE_LOCK_SEAT = HwUrl + "ticket/ticket_api/quick/seat/lock";//锁座
    final static public String HW_MOVIE_UNLOCK_SEAT = HwUrl + "ticket/ticket_api/quick/seat/unlock";//解锁
    final static public String HW_MOVIE_CREAT_ORDER = HwUrl + "ticket/ticket_api/quick/order/submit";//发送订单
    final static public String HW_MOVIE_SEARCH_ORDER = HwUrl + "ticket/ticket_api/quick/order/query";//查询订单
//    品牌
    final static public String HW_PINPAI = HwUrl + "api/brand/query";//品牌
    final static public String HW_PINPAI_CITY = HwUrl + "api/city/query";//城市
    final static public String HW_PINPAI_OPENSHOP = HwUrl + "api/restaurant/query";//开门店
    final static public String HW_PINPAI_ALLSHOP = HwUrl + "api/restaurant/queryAll";//所有店
    final static public String HW_PINPAI_OPENMENU = HwUrl + "api/menu/query";//在卖商品
    final static public String HW_PINPAI_ALLMENU = HwUrl + "api/menu/queryAll";//全部商品
    final static public String HW_PINPAI_MENUDETAIL = HwUrl + "api/menu/details";//商品详细
    final static public String HW_PINPAI_CREAT_ORDER = HwUrl + "api/order/submit";//发送订单
    final static public String HW_PINPAI_SEARCH_ORDER = HwUrl + "api/order/query";//查询订单
//   微信通知结果加解密
public static final int GCM_TAG_LENGTH = 16;
    public static final int AES_KEY_SIZE = 256;
    public static final int GCM_IV_LENGTH = 12;
    public static final String CIPHER_TRANSFORM = "AES/GCM/NoPadding";
    public static final String ALGORITHM_AES = "AES";

    public static final List<String> giftTypeList = Arrays.asList("生日礼", "中秋礼", "过年礼"); ;

    static public String getFlSign(Map<String, String> signMap,Map<String, Object> bizMap){
        net.sf.json.JSONObject resultJson = net.sf.json.JSONObject.fromObject(signMap);
        char[] s = com.alibaba.fastjson.JSONObject.toJSONString(resultJson, SerializerFeature.WriteMapNullValue).toCharArray();
        Arrays.sort(s);
        String outputSignOriginalStr = new String(s) + FlSecret;
        String sign = FlMD5Utils.MD5(outputSignOriginalStr);
        return sign;
    }

    //字节数组转换成十六进制字符串
    private static String bytesToHex(byte[] bytes) {
        StringBuilder sb = new StringBuilder();
        for (byte b : bytes) {
            sb.append(String.format("%02x", b));
        }
        return sb.toString();
    }

    //加密函数
    public static byte[] encrypt(byte[] plainText, SecretKey key, byte[] nonce, byte[] AAD) throws Exception {
        Cipher cipher = Cipher.getInstance(CIPHER_TRANSFORM);
        SecretKeySpec keySpec = new SecretKeySpec(key.getEncoded(), ALGORITHM_AES);
        GCMParameterSpec gcmParameterSpec = new GCMParameterSpec(GCM_TAG_LENGTH * 8, nonce);
        cipher.init(Cipher.ENCRYPT_MODE, keySpec, gcmParameterSpec);
        cipher.updateAAD(AAD);
        byte[] cipherText = cipher.doFinal(plainText);
        return cipherText;
    }

    //解密函数
    public static byte[] decrypt(byte[] cipherText, SecretKey key, byte[] nonce, byte[] AAD) throws Exception{
        Cipher cipher = Cipher.getInstance(CIPHER_TRANSFORM);
        SecretKeySpec keySpec = new SecretKeySpec(key.getEncoded(), ALGORITHM_AES);
        GCMParameterSpec gcmParameterSpec = new GCMParameterSpec(GCM_TAG_LENGTH * 8, nonce);
        cipher.init(Cipher.DECRYPT_MODE, keySpec, gcmParameterSpec);
        cipher.updateAAD(AAD);
        byte[] plainText = cipher.doFinal(cipherText);
        return plainText;
    }

    //微信签名算法
    static public String getWeSign(String[] params,String path) throws NoSuchAlgorithmException, InvalidKeyException, SignatureException, IOException {
        if(params.length==0){
            return null;
        }
        StringJoiner sj = new StringJoiner("\n","","\n");
        for(String i:params){
            sj.add(i);
        }
        Signature signature = Signature.getInstance("SHA256withRSA");
        PrivateKey privateKey= PemUtil.loadPrivateKeyFromPath(path);
        // 初始化Signature实例，使用私钥进行签名
        signature.initSign(privateKey);
        // 更新要签名的数据
        signature.update(sj.toString().getBytes());
        // 对数据进行签名
        byte[] signatureBytes = signature.sign();
        Base64.Encoder encoder=Base64.getEncoder();
        final String sign = encoder.encodeToString(signatureBytes);
        return sign;
    }

    //获取hw签名

    static public String getHwSign(TreeMap<String, Object> map, String key,String flag)  {
        StringJoiner sj;
        String stringSignTemp="";
        //movie和pinpai生成方法不一样
        if(flag.equals("movie")){
            sj = new StringJoiner("&");
            Iterator keyIteratorOfTreeMap = map.keySet().iterator();
            while (keyIteratorOfTreeMap.hasNext()) {
                Object mapKey = keyIteratorOfTreeMap.next();
                sj.add(mapKey.toString() + "=" + map.get(mapKey));
            }
            stringSignTemp= sj.toString() + "&key=" + key;
        }else if(flag.equals("pinpai")){
            sj = new StringJoiner("");
            Iterator keyIteratorOfTreeMap = map.keySet().iterator();
            while (keyIteratorOfTreeMap.hasNext()) {
                Object mapKey = keyIteratorOfTreeMap.next();
                sj.add(mapKey.toString() + map.get(mapKey));
            }
            stringSignTemp = sj.toString() + key;
        }
        String sign = DigestUtils.md5DigestAsHex(stringSignTemp.getBytes(StandardCharsets.UTF_8)).toUpperCase();
        return sign;
         }

    //    获取参数
    static public TreeMap<String, Object> getParams(Object ...args) {
        TreeMap<String,Object> argsMap=new TreeMap<>();
        for(int i=0;i<args.length;i=i+2){
            argsMap.put(args[i].toString(),args[i+1]);
        }
        return argsMap;
    }
    //    获取hw数据
    static public Object getHwData(TreeMap<String, Object> argsMap,String url) {
        MultipartBodyBuilder builder = new MultipartBodyBuilder();
        for (Map.Entry<String, Object> entry : argsMap.entrySet()) {
            builder.part(entry.getKey(), entry.getValue());
        }
//     http接口调用web
        WebClient webClient = WebClient.builder().defaultHeader("Content-Type", "multipart/form-data").baseUrl(url)
                .codecs(obj -> obj.defaultCodecs().maxInMemorySize(10*1024*1024)).build();
        Mono<Object> result = webClient.post()
//                .body(BodyInserters.fromMultipartData("userNo", userNo).with("timestamp", time).with("sign",sign))
                .bodyValue(builder.build())
                .retrieve()
                .bodyToMono(Object.class);
        Object resObj = result.block();
        return resObj;
    }
    static public <T> T  mapToEntity(Map<String, Object> map,Class<T> c) throws IllegalAccessException, InstantiationException, NoSuchFieldException {
            T t = c.newInstance();      //拿到实体类对象
            //1，拆开map,给对象t的属性赋值
            Set<Map.Entry<String, Object>> entries = map.entrySet();
            for (Map.Entry<String, Object> entry : entries) {
                if(isExistField(entry.getKey(),t)) {
                    Field f = c.getDeclaredField(entry.getKey());
                    f.setAccessible(true);  //设置修改权限，因为我们采用的封装private，不修改权限的话，就不能修改实体类中的属性值
                    if(entry.getValue().getClass().equals(f.getType())){
                        f.set(t, entry.getValue());  //传递参数，第一个为实体类对象，第二个为map集合中的value值
                    }
                }
            }
            //2，构建一个实体对象并返回
            return t;
    }
    static public Boolean isExistField(String field, Object obj) {
        if (obj == null || StringUtils.isEmpty(field)) {
            return null;
        }
        Object o = JSON.toJSON(obj);
        JSONObject jsonObj = new JSONObject();
        if (o instanceof JSONObject) {
            jsonObj = (JSONObject) o;
        }
        return jsonObj.containsKey(field);
    }
    static public String decode(String str){
        char[] chars=str.toCharArray();
        char temp=chars[0];
        chars[0]=chars[chars.length-1];
        chars[chars.length-1]=temp;
        return null;
    }
}


